<?php
namespace App\Utils\Server;
use App\Master\Framework\Extend\Module;
use App\Utils\CurlUtil;
use Illuminate\Support\Facades\Cache;

class WeChatServer{
    // 日志模块名
    const LOG_MODULE = 'WeChatServer';

    // 微信公众号配置信息
    protected static $AppID;//微信id
    protected static $AppSecret;//应用id
    protected static $Token;//$Token
    // EasyWeChat Config
    protected static $EasyWeChatConfig;//EasyWeChat配置信息

    // 重定向
    protected static $redirect_uri;

    protected static $instance;
    public function __construct($config,$data)
    {
        self::$AppID  = $config['AppID'];
        self::$AppSecret = $config['AppSecret'];
        self::$Token   = $config['token'];
    }

    public static function getInstance($data = '')
    {
        if (!isset(self::$instance)) {
            $config = Cache::remember('WxConfig',86400,function (){
                return Module::_SetupModule('WxConfig');
            });
            self::$instance = new self($config,$data);
        }
        return self::$instance;
    }
    
    /**
     * 获取code
     * 注意：此方法返回组合连接，并不会主动重定向，需要使用者自己执行
     * @param string $redirect_uri 重定向地址
     * @param array $data 传递参数
     * @param int $type 网页授权类型
     * @return string
     */
    public function code(string $redirect_uri,array $data = [],int $type = 1)
    {
        $url = 'https://open.weixin.qq.com/connect/oauth2/authorize';
        
        if ($type === 1){
            $scope = 'snsapi_base';
        }else{
            $scope = 'snsapi_userinfo';
        }

        $params = [
            'appid' => self::$AppID,
            'redirect_uri' => $redirect_uri,
            'response_type' => 'code',
            'scope' => $scope,//授权方式：snsapi_base：静默授权，snsapi_userinfo高级授权
            'state' => json_encode($data,JSON_UNESCAPED_UNICODE),
            '#wechat_redirect'
        ];
        self::$redirect_uri = $url.'?'.http_build_query($params);
        return self::$redirect_uri;
    }

    /**
     * 网页授权的token
     * @param $code
     * @return mixed
     */
    public function auth_access_token($code)
    {
        $res = Cache::remember('auth_access_token'.md5($code),7200,function ()use($code){
            $url = 'https://api.weixin.qq.com/sns/oauth2/access_token';
            $params = [
                'appid' => self::$AppID,
                'secret' => self::$AppSecret,
                'code' => $code,
                'grant_type' => 'authorization_code'
            ];
            return CurlUtil::get($url,$params);
        });
        return json_decode($res,true);

    }

    /**
     * 获取Access token
     * @return mixed
     */
    public function access_token()
    {
        $res = Cache::remember('client_credential_access_token',7200,function (){
            $url = 'https://api.weixin.qq.com/cgi-bin/token';
            $params = [
                'grant_type' => 'client_credential',
                'appid' => self::$AppID,
                'secret' => self::$AppSecret,
            ];
            return CurlUtil::get($url,$params);
        });
        return json_decode($res,true);
    }

    /**
     * 用户授权拉取信息
     * @param $openid
     * @param $access_token
     * @return mixed
     */
    public function snsapi_userinfo($openid,$access_token)
    {
        $res = Cache::remember('snsapi_userinfo'.md5($openid),7200,function ()use($openid,$access_token){
            $url = 'https://api.weixin.qq.com/sns/userinfo';
            $params = [
                'access_token' => $access_token,
                'openid' => $openid,
                'lang' => 'zh_CN'
            ];
            return CurlUtil::get($url,$params);
        });
        return json_decode($res,true);
    }

    /**
     * 推送模板消息
     * @param $template_id
     * @param $openid
     * @param $data
     * @param string $url
     * @return mixed
     * @throws \Exception
     */
    public function templateMsg($template_id,$openid,$data,string $link = '')
    {
        $token = $this->access_token();
        $url = 'https://api.weixin.qq.com/cgi-bin/message/template/send?access_token='.$token['access_token'] ?? '';

        $params = [
            'touser'=>$openid,
            'template_id'=>$template_id,
            'url'=>$link,
            'data'=>$data
        ];

        $res = CurlUtil::post($url,json_encode($params,JSON_UNESCAPED_UNICODE));
        return json_decode($res,true);
    }

    /**
     * 验证微信token服务器
     * @param $signature
     * @param $timestamp
     * @param $nonce
     * @return bool
     */
    public function checkSignature($signature,$timestamp,$nonce)
    {
        $tmpArr = [self::$Token, $timestamp, $nonce];
        sort($tmpArr, SORT_STRING);
        $tmpStr = implode( $tmpArr );
        $tmpStr = sha1( $tmpStr );

        if ($tmpStr == $signature ) {
            return true;
        } else {
            return false;
        }
    }

    public function send()
    {
        header("Location: ".self::$redirect_uri);
    }
}